package org.easy.socket.server.manager.impl;

import org.easy.socket.server.ClientSession;
import org.easy.socket.server.manager.ISessionManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.smartboot.socket.transport.AioSession;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Description: 客户端会话管理
 * @Author: wxl
 * @CreateTime: 2023/1/10 16:33
 */
public class SessionManager implements ISessionManager {

    private static final Logger logger = LoggerFactory.getLogger(SessionManager.class);

    private final AtomicInteger count = new AtomicInteger();

    private static final Map<String, AioSession> SESSION_MAP = new ConcurrentHashMap<>(1 << 8);

    public SessionManager () {}


    /**
     * 客户端会话管理
     *
     * @param session 会话
     */
    @Override
    public synchronized void addSession(ClientSession session) {
        if (!hasKey(session.getClientId())) {
            SESSION_MAP.put(session.getClientId(), session.getSession());
            // 开启状态监听
            switch (session.getClientStatus()) {
                case NEW_SESSION:
                    logger.info("与客户端:{} 建立连接", session);
                    count.incrementAndGet();
                    break;
                case SESSION_CLOSED:
                    logger.info("断开客户端连接: {}", session);
                    removeSession(session.getClientId());
                    count.decrementAndGet();
                    break;
                case PROCESS_EXCEPTION:
                    logger.info("客户端处理流程异常: {}", session);
                    break;
                case DECODE_EXCEPTION:
                    logger.info("客户端转码异常: {}", session);
                    break;
                case INPUT_EXCEPTION:
                    logger.info("客户端输入异常: {}", session);
                    break;
                case OUTPUT_EXCEPTION:
                    logger.info("客户端输出异常: {}", session);
                    break;
                case INPUT_SHUTDOWN:
                    logger.info("客户端输入关闭异常: {}", session);
                    break;
                default:
            }
        }
    }

    /**
     * 根据客户端ID删除
     *
     * @param clientId 客户端ID
     */
    @Override
    public synchronized void removeSession(String clientId) {
        if (hasKey(clientId)) {
            SESSION_MAP.remove(clientId);
        }
    }

    /**
     * 根据客户端ID获取会话
     *
     * @param clientId 客户端ID
     * @return AioSession
     */
    @Override
    public synchronized AioSession getSession(String clientId) {
        return hasKey(clientId) ? SESSION_MAP.get(clientId) : null;
    }

    private boolean hasKey (String key) {
        return SESSION_MAP.containsKey(key);
    }

}
